package com.apache.poi.word.controller;

import com.deepoove.poi.xwpf.NiceXWPFDocument;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
//import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.internal.MemoryPackagePart;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: HUANG GY.
 * @Date: 2022/2/7 14:10
 * @Description: com.apache.poi.word.controller
 */
@RestController
@RequestMapping("/document")
@Api(value = "文档XWPFDocument")
//@Slf4j
public class DocumentController {

    @GetMapping("/createDoc")
    @ApiOperation(value = "createDoc", notes = "createDoc")
    public Object createDoc() throws Exception {
        XWPFDocument doc = new XWPFDocument();
//        log.debug("doc={}",doc);
        //创建新的段落
        XWPFParagraph p1 = doc.createParagraph();
        // 对齐方式
        p1.setAlignment(ParagraphAlignment.CENTER);
        // 边框
        p1.setBorderBottom(Borders.DOUBLE);
        p1.setBorderTop(Borders.DOUBLE);
        p1.setBorderRight(Borders.DOUBLE);
        p1.setBorderLeft(Borders.DOUBLE);
        p1.setBorderBetween(Borders.SINGLE);
        XWPFRun run1 = p1.createRun();
        run1.addBreak();
        run1.setText("举办广西壮族自治区第十四届运动会是以习近平新时代中国特色社会主义思想为指导，深入贯彻落实党的十九大精神，进一步深化我区体育体制改革，以群众参与，人民满意为导向，增加群众的参与度、获得感和满足感，努力使举办自治区运动会成为推动健康广西建设的重要展示窗口和舞台，成为群众体育与竞技体育协调发展的有效平台，成为弘扬体育文化、传承体育精神、推动广西体育事业改革发展的助推器和风向标，成为全区人民关注度高，热烈、精彩、和谐的高水平体育盛会，为建设体育强区、重振广西体育雄风做出积极贡献。");

        // 段落起始插入XWPFRun
        XWPFRun insertNewRun = p1.insertNewRun(0);
        insertNewRun.setText("在段落起始位置插入这段文本");

        List<XWPFRun> runs = p1.getRuns();
        // setText默认为追加文本，参数0表示设置第0个位置的文本，覆盖上一次设置
        runs.get(0).setText("追加文本", 0);
        runs.get(0).setText("修改文本", 0);
        FileOutputStream out = new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\write.docx");
        doc.write(out);
        if (out!=null) {
            out.close();
        }
        if (doc!=null) {
            doc.close();
        }

        return "啊哈哈test001";
    }

    @GetMapping("/createPic")
    @ApiOperation(value = "createPic", notes = "createPic")
    public Object createPic() throws Exception {
        XWPFDocument doc = new XWPFDocument();

//        long LEFT_MARGIN = 1800L;
//        long RIGHT_MARGIN = 1800L;
//        long TOP_MARGIN = 1440L;
//        long BOTTOM_MARGIN = 1440L;

        long LEFT_MARGIN = 0L;
        long RIGHT_MARGIN = 0L;
        long TOP_MARGIN = 0L;
        long BOTTOM_MARGIN = 0L;

        CTBody body = doc.getDocument().getBody();
        if (!body.isSetSectPr()) {
            body.addNewSectPr();
        }
        CTSectPr sectPr = body.getSectPr();

        if (!sectPr.isSetPgSz()) {
            sectPr.addNewPgSz();
        }

        if (!sectPr.isSetPgMar()) {
            sectPr.addNewPgMar();
        }

        CTPageMar pageMar = sectPr.getPgMar();
        CTPageSz pgSz = sectPr.getPgSz();
        pageMar.setLeft(BigInteger.valueOf(LEFT_MARGIN));
        pageMar.setRight(BigInteger.valueOf(RIGHT_MARGIN));
        pageMar.setTop(BigInteger.valueOf(TOP_MARGIN));
        pageMar.setBottom(BigInteger.valueOf(BOTTOM_MARGIN));

        InputStream inputStream = new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\bb.jpg");
        XWPFParagraph p1 = doc.createParagraph();
        XWPFRun run = p1.createRun();
//        run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(612), Units.toEMU(800));
        run.addPicture(inputStream, XWPFDocument.PICTURE_TYPE_PNG, "Generated", Units.toEMU(614), Units.toEMU(793));

//        CTPageMar pageMar2 = sectPr.addNewPgMar();
//        pageMar2.setLeft(BigInteger.valueOf(1800L));
//        pageMar2.setRight(BigInteger.valueOf(1800L));
//        pageMar2.setTop(BigInteger.valueOf(1800L));
//        pageMar2.setBottom(BigInteger.valueOf(1800L));
        run.addPicture(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\bb.jpg"), XWPFDocument.PICTURE_TYPE_PNG, "Generated",  Units.toEMU(614), Units.toEMU(793));
        FileOutputStream out = new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\createPic.docx");
        doc.write(out);
        if (out!=null) {
            out.close();
        }
        if (doc!=null) {
            doc.close();
        }

        return "啊哈哈test001";
    }


    @GetMapping("/createPicOver")
    @ApiOperation(value = "createPicOver", notes = "createPicOver")
    public static Object createPicOver() throws Exception {
        XWPFDocument doc = new XWPFDocument();
        InputStream in = new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\bb.jpg");

        XWPFParagraph paragraph = doc.createParagraph();
        XWPFRun run = paragraph.createRun();
        run.addPicture(in, Document.PICTURE_TYPE_PNG, "TEST", Units.toEMU(596), Units.toEMU(840));
        CTDrawing drawing = run.getCTR().getDrawingArray(0);
        CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
        CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "TEST1",
                Units.toEMU(596), Units.toEMU(840),//图片大小
                Units.toEMU(-89), Units.toEMU(-71), false);//相对当前段落位置 需要计算段落已有内容的左偏移
        drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
        drawing.removeInline(0);//删除行内属性


//        for (int i = 0; i < 50; i++) {
//            run.addCarriageReturn();
//        }
        doc.createParagraph().setPageBreak(true);

//        doc.createParagraph().createRun().addPicture(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\white.png"), Document.PICTURE_TYPE_PNG, "TEST", Units.toEMU(420), Units.toEMU(678));
        XWPFRun runTwo = doc.createParagraph().createRun();
        runTwo.addPicture(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\bb.jpg"), Document.PICTURE_TYPE_PNG, "TEST", Units.toEMU(596), Units.toEMU(840));
        CTDrawing drawingTwo = runTwo.getCTR().getDrawingArray(0);
        CTGraphicalObject graphicalobjectTwo = drawingTwo.getInlineArray(0).getGraphic();
        CTAnchor anchorTwo = getAnchorWithGraphic(graphicalobjectTwo, "TEST1",
                Units.toEMU(596), Units.toEMU(840),//图片大小
                Units.toEMU(-89), Units.toEMU(-71), false);//相对当前段落位置 需要计算段落已有内容的左偏移
        drawingTwo.setAnchorArray(new CTAnchor[]{anchorTwo});//添加浮动属性
        drawingTwo.removeInline(0);//删除行内属性

//        doc.createParagraph().createRun().addPicture(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\white.png"), Document.PICTURE_TYPE_PNG, "TEST", Units.toEMU(420), Units.toEMU(678));


        createHeader( doc);

        doc.createParagraph().setPageBreak(true);
        doc.createParagraph().setPageBreak(true);
        doc.createParagraph().setPageBreak(true);



        FileOutputStream out = new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\createPicOver.docx");
        doc.write(out);
        if (out!=null) {
            out.close();
        }
        if (doc!=null) {
            doc.close();
        }

        return "啊哈哈test001";
    }

    public static void createHeader( XWPFDocument doc) throws Exception {
        CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy( doc, sectPr );
        XWPFHeader header = headerFooterPolicy.createHeader( XWPFHeaderFooterPolicy.DEFAULT );
        XWPFParagraph paragraph = header.createParagraph();
        paragraph.setAlignment( ParagraphAlignment.RIGHT );
        paragraph.setVerticalAlignment(TextAlignment.BOTTOM);
        paragraph.setBorderBottom( Borders.THICK );
        XWPFRun run = paragraph.createRun();
        List<XWPFPictureData> allPackagePictures = header.getAllPackagePictures();
        String [] imgFileArr = {"D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\yemei1.png","D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\yemei2.png","D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\yemei3.png"};
        XWPFPicture [] pictureArr = new XWPFPicture[3];
        for (int i = 0; i < imgFileArr.length; i++) {
            pictureArr[i] = run.addPicture( new FileInputStream(imgFileArr[i]), XWPFDocument.PICTURE_TYPE_JPEG, imgFileArr[i], Units.toEMU( 150 ), Units.toEMU( 50 ) );
            allPackagePictures = header.getAllPackagePictures();
            List<XWPFPictureData> allPackagePictureList = new ArrayList(allPackagePictures);
            allPackagePictureList.sort((o1,o2)->{
                return o1.getFileName().compareTo(o2.getFileName());
            });
            for (XWPFPictureData picturedata : allPackagePictureList) {
                String blipID = header.getRelationId( picturedata );
                pictureArr[i].getCTPicture().getBlipFill().getBlip().setEmbed( blipID );
            }
        }

        for (int i = 0; i < 3; i++) {
            CTDrawing drawingTwo = run.getCTR().getDrawingArray(i);
            CTGraphicalObject graphicalobjectTwo = drawingTwo.getInlineArray(0).getGraphic();
            CTAnchor anchorTwo = getAnchorWithGraphic(graphicalobjectTwo, "TEST1",
                    Units.toEMU(150), Units.toEMU(40),//图片大小
                    Units.toEMU(150*i), Units.toEMU(-0), false);//相对当前段落位置 需要计算段落已有内容的左偏移
            drawingTwo.setAnchorArray(new CTAnchor[]{anchorTwo});//添加浮动属性
            drawingTwo.removeInline(0);//删除行内属性
        }
        run.addCarriageReturn();
        run.addCarriageReturn();
        run.setText("                                                                               乒乓球   2022.10.01        " );

        //添加页脚   https://blog.csdn.net/dh1027/article/details/78095940  页码
        XWPFFooter footer =  headerFooterPolicy.createFooter(STHdrFtr.DEFAULT);
        XWPFParagraph paragraphFoot = footer.createParagraph();

        /*
         * 给段落创建元素
         * 设置元素字面为公司地址+公司电话
         * */
        run = paragraphFoot.createRun();
        run.setText("fjakjfskad我你等到他哈哈哈的额");
        setXWPFRunStyle(run,"Arial",10);
        run.addTab();

        run = paragraphFoot.createRun();
        CTFldChar fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

        run = paragraphFoot.createRun();
        CTText ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("PAGE  \\* MERGEFORMAT");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
        setXWPFRunStyle(run,"Arial",10);

        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));
        run = paragraphFoot.createRun();
        run.setText("/");
        setXWPFRunStyle(run,"Arial",10);
        run.addTab();

        run = paragraphFoot.createRun();
        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

        run = paragraphFoot.createRun();
        ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("NUMPAGES  \\* MERGEFORMAT ");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
        setXWPFRunStyle(run,"Arial",10);

        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));




    }

    /**
     * @param ctGraphicalObject 图片数据
     * @param deskFileName      图片描述
     * @param width             宽
     * @param height            高
     * @param leftOffset        水平偏移 left
     * @param topOffset         垂直偏移 top
     * @param behind            文字上方，文字下方
     * @return
     * @throws Exception
     */
    public static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
                                                String deskFileName, int width, int height,
                                                int leftOffset, int topOffset, boolean behind) {
        String anchorXML =
                "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
                        + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
                        + "<wp:positionH relativeFrom=\"column\">"
                        + "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
                        + "</wp:positionH>"
                        + "<wp:positionV relativeFrom=\"paragraph\">"
                        + "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
                        "</wp:positionV>"
                        + "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
                        + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
                        + "<wp:wrapNone/>"
                        + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
                        + "</wp:anchor>";

        CTDrawing drawing = null;
        try {
            drawing = CTDrawing.Factory.parse(anchorXML);
        } catch (XmlException e) {
            e.printStackTrace();
        }
        CTAnchor anchor = drawing.getAnchorArray(0);
        anchor.setGraphic(ctGraphicalObject);
        return anchor;
    }


    @GetMapping("/readDoc")
    @ApiOperation(value = "readDoc", notes = "readDoc")
    public Object readDoc() throws Exception {
        XWPFDocument doc = new XWPFDocument(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\test001.docx"));
        List<XWPFParagraph> paragraphs = doc.getParagraphs();
//        log.debug("paragraphs={}",paragraphs);
        // 表格
        List<XWPFTable> tables = doc.getTables();
//        log.debug("tables={}",tables);
        // 图片
        List<XWPFPictureData> allPictures = doc.getAllPictures();
        // 页眉
        List<XWPFHeader> headerList = doc.getHeaderList();
        // 页脚
        List<XWPFFooter> footerList = doc.getFooterList();
        return "啊哈哈test001";
    }

    @GetMapping("/docHeadFoot")
    @ApiOperation(value = "docHeadFoot", notes = "docHeadFoot")
    public static Object docHeadFoot() throws Exception {
        XWPFDocument doc = new XWPFDocument(new FileInputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/若依环境使用手册.docx"));
        /*
         * 生成页脚段落
         * 给段落设置宽度为占满一行
         * 为公司地址和公司电话左对齐，页码右对齐创造条件
         * */
        CTSectPr sectPr = doc.getDocument().getBody().addNewSectPr();
        XWPFHeaderFooterPolicy headerFooterPolicy = new XWPFHeaderFooterPolicy(doc, sectPr);
        XWPFFooter footer =  headerFooterPolicy.createFooter(STHdrFtr.DEFAULT);
        XWPFParagraph paragraph = footer.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.LEFT);
        paragraph.setVerticalAlignment(TextAlignment.CENTER);
        paragraph.setBorderTop(Borders.THICK);
        CTTabStop tabStop = paragraph.getCTP().getPPr().addNewTabs().addNewTab();
        tabStop.setVal(STTabJc.RIGHT);
        int twipsPerInch =  1440;
        tabStop.setPos(BigInteger.valueOf(6 * twipsPerInch));

        /*
         * 给段落创建元素
         * 设置元素字面为公司地址+公司电话
         * */
        XWPFRun run = paragraph.createRun();

        run.setText(("观日路22号203-1") + ("13646933185"));
        setXWPFRunStyle(run,"Arial",10);
        run.addTab();

        /*
         * 生成页码
         * 页码右对齐
         * */
        run = paragraph.createRun();
        run.setText("第");
        setXWPFRunStyle(run,"Arial",10);

        run = paragraph.createRun();
        CTFldChar fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

        run = paragraph.createRun();
        CTText ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("PAGE  \\* MERGEFORMAT");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
//        setXWPFRunStyle(run,"Arial",10);

        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));

        run = paragraph.createRun();
        run.setText("页 总共");
//        setXWPFRunStyle(run,"Arial",10);

        run = paragraph.createRun();
        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("begin"));

        run = paragraph.createRun();
        ctText = run.getCTR().addNewInstrText();
        ctText.setStringValue("NUMPAGES  \\* MERGEFORMAT ");
        ctText.setSpace(SpaceAttribute.Space.Enum.forString("preserve"));
        setXWPFRunStyle(run,"Arial",10);

        fldChar = run.getCTR().addNewFldChar();
        fldChar.setFldCharType(STFldCharType.Enum.forString("end"));

        run = paragraph.createRun();
        run.setText("页");
        setXWPFRunStyle(run,"Arial",10);
        doc.write(new FileOutputStream("/Users/huangguoye/IdeaProjects/gitee/word/word-demo/src/main/resources/docs/若依环境使用手册001.docx"));
        doc.setCommitted(true);
        return "啊哈哈test001";
    }

    /**
     * 设置页脚的字体样式
     *
     * @param r1 段落元素
     */
    private  static  void setXWPFRunStyle(XWPFRun r1,String font,int fontSize) {
        r1.setFontSize(fontSize);
        CTRPr rpr = r1.getCTR().isSetRPr() ? r1.getCTR().getRPr() : r1.getCTR().addNewRPr();
//        CTFonts fonts =  rpr.addNewRFonts();
//        fonts.setAscii(font);
//        fonts.setEastAsia(font);
//        fonts.setHAnsi(font);
    }

    @GetMapping("/mergeDoc")
    @ApiOperation(value = "mergeDoc", notes = "mergeDoc")
    public Object mergeDoc() throws Exception {
        NiceXWPFDocument main = new NiceXWPFDocument(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\createPic.docx"));
        NiceXWPFDocument sub = new NiceXWPFDocument(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\test001.docx"));
        // 合并两个文档
        NiceXWPFDocument newDoc = main.merge(sub);
        // 生成新文档
        FileOutputStream out = new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\mergeDoc.docx");
        newDoc .write(out);
        newDoc .close();
        out.close();
        return "啊哈哈test001";
    }

    @GetMapping("/updateTOC")
    @ApiOperation(value = "updateTOC", notes = "updateTOC")
    public static Object updateTOC() throws Exception {
        NiceXWPFDocument doc = new NiceXWPFDocument(new FileInputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\work1\\newDoc.docx"));
        doc.enforceUpdateFields();
        // 生成新文档
        FileOutputStream out = new FileOutputStream("D:\\05_code\\gitee\\word-demo\\src\\main\\resources\\docs\\work1\\newDocTOC.docx");
        doc .write(out);
        doc .close();
        out.close();
        return "啊哈哈test001";
    }

    public static void main(String[] args) throws Exception {
//        createPicOver();
//        docHeadFoot();
//        updateTOC();
        docHeadFoot();
    }

}
